LSI TinyRisc development

Contents|Index|Previous|Next
LSI TinyRisc development

The following documentation describes information pertinent only to LSI TinyRISC processors using GNUPro Toolkit software.

- Compiler features for LSI TinyRISC
- ABI summary for LSI TinyRISC
- Assembler features for the LSI TinyRISC
- Linker features for the LSI TinyRISC
- Debugger features for the LSI TinyRISC
- Stand-alone simulator issues for LSI TinyRISC

### Compiler features for LSI TinyRISC

The following features for the GNUPro compiler have support for the LSI TinyRISC processor.
The following MIPS16-specific command-line options are supported. For a list of all the available generic compiler options, see GNU CC command options in Using GNU CC in GNUPro Compiler Tools.
`-mips16`

> Compile code for the processor in mips16 mode.

`-mentry`

> The `-mentry` option tells the compiler to use the entry and exit pseudo-instructions for function entry and exit. The pseudo-instructions save and restore registers at function entry and exit. These work by triggering an unimplemented instruction trap. Your exception handler must handle these instructions correctly. This is a time/space tradeoff; code using the entry and exit instructions is smaller, but takes longer to execute.

`-EB`
`-EL`

> Any MIPS configuration of the compiler can select big-endian or little-endian output at run time. Use `-EB` to select big-endian output and `-EL` for little-endian. If neither `-EL` nor `-EB` are defined, big-endian is the default.

See Preprocessor symbols for the preprocessor symbols and the compiler options that define them.
Preprocessor symbols

Symbol | Compiler options that define symbol
`_mips16` | Only if `-mips16` is used
`mips` | Only if `-ansi` not used
`_mips` | Only if `-ansi` not used
`_ _mips` | Always defined
`MIPSEB` | Only if `-ansi` and `-EL` are not used
`_MIPSEB` | Only if `-EL` is not used
`_ _MIPSEB` | Only if `-EL` is not used
`_ _MIPSEB_ _` | Only if `-EL` is not used
`MIPSEL` | Only if `-ansi` is not used and `-EL` is used
`_MIPSEL` | only if `-EL` is used
`__MIPSEL` | only if `-EL` is used
`__MIPSEL__` | only if `-EL` is used

### ABI summary for LSI TinyRISC

The following documentation details the Application Binary Interface (ABI) for the LSI TinyRISC processor.

- Data type sizes and alignments for the LSI TinyRISC
- Register allocation definitions for the LSI TinyRISC
- Stack frame features for the LSI TinyRISC
- Calling conventions for LSI TinyRISC

#### Data type sizes and alignments for the LSI TinyRISC

The following information defines the data type sizes and alignments. The stack is aligned on eight-byte boundaries.

`char` | 1 byte
`short` | 2 bytes
`int` | 4 bytes
`long` | 4 bytes
`long long` | 8 bytes
`float` | 4 bytes
`double` | 8 bytes
`long double` | 8 bytes
pointer | 4 bytes

#### Register allocation definitions for the LSI TinyRISC

See Register allocation definitions.

###### Register allocation definitions

General purpose (integer) register | Usage
Constant zero | `$0`
Volatile | `$1` through `$15` , `$24` , `$25`
Saved | `$16` through `$23` , `$30`
Parameters | `$4` through `$7`
Kernel reserved | `$26` , `$27`
Global pointer | `$28`
Stack pointer | `$29`
Frame pointer | `$30`
Return address | `$31`

> Note:
> Do not depend on the order of the registers shown in Register allocation definitions. Instead, use GCC’s `asm( )` extension and allow the compiler to schedule registers.

#### Stack frame features for the LSI TinyRISC

The following specific issues for the stack frame have support for the LSI TinrRISC processor. See also Stack frame for LSI TinyRISC (below).

- The stack grows downwards from high addresses to low addresses.
- A leaf function need not allocate a stack frame if it does not need one.
- A frame pointer need not be allocated.
- The stack pointer shall always be aligned to 8 byte boundaries.

###### Stack frame for LSI TinyRISC

#### Calling conventions for LSI TinyRISC

The following documentation defines the calling conventions for the LSI TinyRISC processor.

- Argument passing for the LSI TinyRISC
- Function return values for the LSI TinyRISC

##### Argument passing for the LSI TinyRISC

When compiling in mips16 mode, the floating point registers are not available. A function compiled in mips16 mode expects floating point arguments in the general registers, and it returns a floating point value in the general registers. The compiler and the linker cooperate to make this happen transparently when a function compiled in mips16 mode calls a function compiled in mips32 mode, or vice-versa. If you write your own assembly language code, and plan to call between mips16 code and mips32 code, you must arrange for the function arguments and return values to be in the right place for both the caller and the callee.
On the mips16, floating point values are returned as though they were integer values. A single precision floating point value is returned in general register ``$2`'. A double precision floating point value is returned in general registers ``$2`' and ``$3`'.
The compiler passes arguments to a function using a combination of integer general registers, and the stack. The number, type, and relative position of arguments in the calling functions argument list define the combination of registers and memory used. The general registers ``$4..$7`' pass the first few arguments.
If the function being called returns a structure or union, the calling function passes the address of an area large enough to hold the structure to the function in ``$4`'. The function being called copies the returned structure into this area before returning. The address in ``$4`' becomes the first argument to the function for the purpose of argument register allocation. All user arguments are then shifted down by one.

The compiler always allocates space on the stack for all arguments even when some or all of the arguments to a function are passed in registers. This stack space is a large enough structure to contain all the arguments. After promotion and structure return pointer insertion, the arguments are aligned according to normal structure rules. Locations used for arguments within the stack frame are referred to as the home locations. Whenever possible, arguments declared in variable argument lists, as with those defined using a ``va_list`' declaration, are passed in the integer registers, even when they are floating-point numbers.

If the first argument is an integer, remaining arguments are passed in the integer registers.

The compiler passes structures and unions as if they were very wide integers with their size rounded up to an integral number of words. The "fill bits" necessary for rounding up are undefined. A structure can be split so that a portion is passed in registers and the remainder passed on the stack. In this case, the first words are passed in ``$4`', ``$5`', ``$6`', and ``$7`' as needed, with additional words passed on the stack.

The rules for assigning which arguments go into registers and which arguments must be passed on the stack can be explained by considering the list of arguments itself as a structure, aligned according to normal structure rules. Mapping of this structure into the combination of registers and stack is as follows; everything with a structure offset greater than or equal to 32 is passed on the stack. The remainder of the arguments are passed in ``$4..$7`' based on their structure offset. Any holes left in the structure for alignment are unused, whether in registers or on the stack.

##### Function return values for the LSI TinyRISC

A function can return no value, an integral or pointer value, a floating-point value (single or double precision), or a structure; unions are treated the same as structures.
A function that returns no value puts no particular value in any register.
A function that returns an integral or pointer value places its result in register ``$2`'.
A function that returns a floating-point value places its result in general register ``$2`'.

The caller to a function that returns a structure or a union passes the address of an area large enough to hold the structure in register ``$4`'. The function returns a pointer to the returned structure in register ``$2`'.

### Assembler features for the LSI TinyRISC

The following documentation defines the specific assembler options for the LSI TinyRISC processor. For a list of available generic assembler options, see Command-line options in Using `as` in GNUPro Utilities.
`-mips16`

> Assemble code for the processor in mips16 mode.

`-EB`
`-EL`

> Any MIPS configuration of the assembler can select big-endian or little-endian output at run time.

> Use ``-EB`' to select big-endian output, and ``-EL`' for little-endian. The default is big-endian.

> For information about the MIPS instruction set, see MIPS RISC Architecture (Kane and Heindrich, Prentice-Hall). For an overview of MIPS assembly conventions, see "Appendix D: Assembly Language Programming" in the same volume.

> There are 32 64-bit general (integer) registers, named ``$0..$31`'. There are 32 64-bit floating point registers, named ``$f0..$f31`'.

For assembler mnemonics, see MIPS16 ASE Reference Manual.

### Linker features for the LSI TinyRISC

For a list of available generic linker options, see Linker scripts in Using `ld` in GNUPro Utilities. In addition, the following MIPS-specific command-line options have support.
`-EL`

> Link objects for the processor in little endian mode.

`-EB`

> Link objects for the processor in big-endian mode.

#### Linker script for LSI TinyRISC

The GNU linker uses a linker script to determine how to process each section in an object file, and how to lay out the executable. The linker script is a declarative program consisting of a number of directives. For instance, the directive ``ENTRY( )`' specifies which symbol in the executable is designated the executable’s entry point. Since linker scripts can be complicated to write, the linker includes one built-in script that defines the default linking process.
Use the following linker script (``lsi.ld`') when linking programs for the TinyRISC board. Also, use it to link programs for execution in the MIPS simulator.

>     /* The following TEXT start address leaves space for the monitor

>     workspace. */

>     ENTRY(_start)

>     OUTPUT_ARCH("mips:4000")

>     OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")

>     GROUP(-lc -llsi -lgcc)

>     SEARCH_DIR(.)

>     __DYNAMIC = 0;

>     /*

>     * Allocate the stack to be at the top of memory, since the

>     * stack grows down

>     */

>     PROVIDE (__stack = 0);

>     /* PROVIDE (__global = 0); */

>     /*

>     * Initalize some symbols to be zero so we can reference them

>     * in the crt0 without core dumping. These functions are all

>     * optional, but we do this so we can have our crt0 always use

>     * them if they exist. This is so BSPs work better when using

>     * the crt0 installed with gcc. We must initalize them twice,

>     * so we multiple object file formats, as some prepend an

>     * underscore. */

>     PROVIDE (hardware_init_hook = 0);

>     PROVIDE (software_init_hook = 0);

>     SECTIONS

>     {

>     . = 0xA0020000;

>     .text : {

>     _ftext = . ;

>     *(.init)

>     eprol = .;

>     *(.text)

>     PROVIDE (__runtime_reloc_start = .);

>     *(.rel.sdata)

>     PROVIDE (__runtime_reloc_stop = .);

>     *(.fini)

>     etext = .;

>     _etext = .;

>     }

>     . = .;

>     .rdata : {

>     *(.rdata)

>     }

>     _fdata = ALIGN(16);

>     .data : {

>     *(.data)

>     CONSTRUCTORS

>     }

>     . = ALIGN(8);

>     _gp = . + 0x8000;

>     __global = _gp;

>     .lit8 : {

>     *(.lit8)

>     }

>     .lit4 : {

>     *(.lit4)

>     }

>     .sdata : {

>     *(.sdata)

>     }

>     edata = .;

>     _edata = .;

>     _fbss = .;

>     .sbss : {

>     *(.sbss)

>     *(.scommon)

>     }

>     .bss : {

>     _bss_start = . ;

>     *(.bss)

>     *(COMMON)

>     }

>     end = .;

>     _end = .;

>     }

### Debugger features for the LSI TinyRISC

GDB uses the MIPS remote debugging protocol to talk to a target via a serial port. To run a program on the TinyRISC board, start up GDB with the name of your program as the argument to the GDB call: `mips-lsi-elf-gdb`<`program`>, for example.
Use the ``target lsi` <`port`>' command to specify the connection to your target board, where `<`port`>'is the name of the serial port connected to the board. If the program has not already been downloaded to the board, use the ``load`' command to download it. You can then use all the usual GDB commands. For example, the following sequence connects to the target board through a Unix serial port, and loads and runs a program called ``prog`' through the debugger.

    mips-lsi-elf-gdb prog

    GDB is free software and . . .

    (gdb)target lsi /dev/ttyb

    (gdb)load prog

    (gdb)run

    On PC platforms, substitute the specific COM port:

    C:\> mips-lsi-elf-gdbprog

    GDB is free software and . . .

    (gdb)target lsi com3

    (gdb)load prog

    (gdb)run

#### Special commands for LSI TinyRISC

GDB also supports the following special commands for MIPS targets.
`set remotedebug num`
`show remotedebug`

> For this to be useful, you must know something about the MIPS debugging protocol, also called ``rmtdbg`'. An informal description can be found in the GDB source files, specifically in the ``remote-mips.c`' file .

> You can see some debugging information about communications with the board by setting the ``remotedebug`'variable. If you set it to 1 using the ``set remotedebug 1`' command, every packet is displayed. If you set it to 2, every character is displayed. You can check the current value at any time with the ``showremotedebug`' command.

`set timeout seconds`
`set retranjut`
`show retransmit-timeout`

> You can control the timeout used while waiting for a packet, in the MIPS debugging protocol, with the ``set timeout seconds`' command. The default is 5 seconds. Similarly, you can control the timeout used while waiting for an acknowledgment of a packet with the `set retransmit-timeout seconds` command. The default is 3 seconds. You can inspect both values with the ``show timeout`' and ``show retransmit-timeout`' commands.

> The timeout set by ``set timeout`' does not apply when GDB is waiting for your program to stop. In that case, GDB waits forever because it has no way of knowing how long the program is going to run before stopping.

### Stand-alone simulator issues for LSI TinyRISC

Three run-time command-line options are available with the stand-alone simulator: `-t`, `-v`, and `-m`, as the following documentation describes.
The ``-t`' command-line option to the stand-alone simulator turns on tracing of all memory fetching and storing in the simulator, as the following example shows.

>     C:\>mips-lsi-elf-run -t hello.xb

>     C:\>

The simulator writes the trace information to the file ``trace.din`'. The following example shows the first few lines of a trace file.

>     2 a0020000 ; width 4 ; load instruction

>     2 a0020004 ; width 4 ; load instruction

>     2 a0020008 ; width 4 ; load instruction

>     2 a002000c ; width 4 ; load instruction

>     2 a0020010 ; width 4 ; load instruction

>     2 a0020014 ; width 4 ; load instruction

>     2 a0020018 ; width 4 ; load instruction

>     2 a002001c ; width 4 ; load instruction

>     2 a0020020 ; width 4 ; load instruction

>     2 a0020024 ; width 4 ; load instruction

>     . . .

The ``-v`' command-line option prints some simple statistics, as the following example shows.

>     %mips-lsi-elf-run -v hello.xb

>     mips-lsi-elf-run hello

>     Hello, world!

>     3 + 4 = 7

>     MIPS 32-bit simulator

>     Big endian memory model

>     0x00200000 bytes of memory at 0xa0000000

>     Instruction fetches = 4138

>     Pipeline ticks = 4138

The ``-m`' command-line option sets the size of the simulated memory area. The default size is 1048576 bytes (1 megabyte). The simulator rounds up the size you request to the next power of two. See the following example script for details.

>     %mips-lsi-elf-run -v -m 200000 hello.xb

>     mips-lsi-elf-run hello

>     Hello, world!

>     3 + 4 = 7

>     MIPS 32-bit simulator

>     Big endian memory model

>     0x00040000 bytes of memory at 0xa0000000

>     Instruction fetches = 4138

>     Pipeline ticks = 4138

Top|Contents|Index|Previous|Next